﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ListViewTest
{

    public partial class Form1 : Form
    {
        List<MasterImport> t;
        public Form1()
        {
            InitializeComponent();
            t = new List<MasterImport>();
            t.Add(new MasterImport() { Name = "Veco", Age = 27 });
            t.Add(new MasterImport() { Name = "Kosta", Age = 27 });
            t.Add(new MasterImport() { Name = "Senih", Age = 29 });
            t.Add(new MasterImport() { Name = "Ante", Age = 30 });
            t.Add(new MasterImport() { Name = "Dance", Age = 27 });
            t.Add(new MasterImport() { Name = "Dragan", Age = 29 });
            t.Add(new MasterImport() { Name = "Solakov", Age = 25 });

            var a = new Random();
            for (int i = 0; i < 200000; i++)
            {

                t.Add(new MasterImport() { Name = Guid.NewGuid().ToString(), Age = (int)(a.NextDouble() * 100000) });
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dataGridView1.DataSource = t;
        }

        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            string strColumnName = dataGridView1.Columns[e.ColumnIndex].DataPropertyName;
            SortOrder strSortOrder = getSortOrder(e.ColumnIndex);
            dataGridView1.DataSource = getData(txtName.Text, strColumnName, strSortOrder);
            dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = strSortOrder;
        }


        private SortOrder getSortOrder(int columnIndex)
        {
            if (dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.None ||
                dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.Descending)
            {
                dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
                return SortOrder.Ascending;
            }
            else
            {
                dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
                return SortOrder.Descending;
            }
        }

        private void txtName_TextChanged(object sender, EventArgs e)
        {
            timer1.Start();
            
        }
        private IEnumerable<MasterImport> getData(string filter, string orderBy, SortOrder direction)
        {
            var result = t;
            if (!String.IsNullOrEmpty(filter))
            {
                result = result.Where(p =>
                {
                    foreach (var item in p.GetType().GetProperties())
                    {
                        if (item.GetValue(p, null).ToString().ToLower().Contains(filter.ToLower()))
                            return true;
                    }
                    return false;
                }).ToList();
            }
            if (!String.IsNullOrEmpty(orderBy))
            {
                if (direction == SortOrder.Ascending)
                {
                    result = result.OrderBy(p =>
                    {
                        return p.GetType().GetProperty(orderBy).GetValue(p, null);
                    }).ToList();
                }
                else
                {
                    result = result.OrderByDescending(p =>
                    {
                        return p.GetType().GetProperty(orderBy).GetValue(p, null);
                    }).ToList();
                }
            }
            return result;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //var v = t.Where(p => p.Name.ToLower().Contains(txtName.Text.ToLower())).ToList();
            dataGridView1.DataSource = getData(txtName.Text, string.Empty, SortOrder.None);
            timer1.Stop();
        }
    }
}
